package com.googlecode.jtoy.productorandconsumer;

import java.util.concurrent.LinkedBlockingQueue;

/**
 * BlockingQueue也是JDK5.0的一部分，它是一个已经在内部实现了同步的队列，实现方式采用的是我们的第2种await()/signal()方法。
 * 它可以在生成对象时指定容量大小。 它用于阻塞操作的是put()和take()方法。 put()方法类似于我们上面的生产者线程，容量最大时，自动阻塞。
 * take()方法类似于我们上面的消费者线程，容量为0时，自动阻塞。
 * 
 * @author shangxj
 * @date Sep 12, 2011 11:44:06 AM
 */
public class BlockingQueue {

	private LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<String>(10);
	private int MAX = 10;
	private int i = 0;

	public static void main(String[] args) {
		new BlockingQueue().start();
	}

	public void start() {
		new Productor().start();
		new Consumer().start();
		new Consumer().start();
	}

	class Productor extends Thread {
		public void run() {
			while (true) {

				try {
					Thread.sleep((long) (100 * Math.random()));
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}

				synchronized (this) {
					try {
						if (queue.size() == MAX) {
							System.out.println("warning: it's full!");
						}
						String product = String.valueOf(++i);
						queue.put(product);
						System.out.println("Productor: ++++++++++++++++++++" + product);
					} catch (InterruptedException e) {
						System.out.println("productor is interrupted!");
					}
				}
			}
		}
	}

	class Consumer extends Thread {
		public void run() {
			while (true) {
				try {
					Thread.sleep((long) (200 * Math.random()));   
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
				
				synchronized (this) {
					try {
						if (queue.size() == 0) {
							System.out.println("warning: it's empty!");
						}
						String product = queue.take();
						System.out.println("Consumer: --------------------" + product);
					} catch (InterruptedException e) {
						System.out.println("productor is interrupted!");
					}
				}
			}
		}
	}

}
